/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package MapPack;

/**
 *
 * @author Aaron
 */

import EntityPack.Entity;
import com.badlogic.gdx.math.Vector2;

import java.util.ArrayList;
import java.util.HashMap;

public class Map {
    private final int chunkSize;
    private final int chunkRadius;
    private final HashMap<Vector2, Chunk> chunks;
    private final Cell worldSpawn;

    public Map (int chunkSize, int chunkRadius, int spawnX, int spawnY) {

        chunks = new HashMap<>();
        this.chunkSize = chunkSize;
        this.chunkRadius = chunkRadius;

        // Create the map chunks.
        for (int i = -chunkRadius; i < chunkRadius; i++) {
            for (int j = -chunkRadius; j < chunkRadius; j++) {
                this.chunks.put(new Vector2(i, j), new Chunk(this, new Vector2(i, j), chunkSize));
            }
        }

        // Set the spawn point.
        Cell potentialSpawn = getMapCell(spawnX, spawnY);
        if (potentialSpawn == null) {
            this.worldSpawn = getMapCell(0, 0);
        } else {
            this.worldSpawn = potentialSpawn;
        }
    }

    public Cell getMapCell(int x, int y) {

        Cell result = null;

        // Start with the chunk that hosts the given coordinate.
        Chunk chunk = chunks.get(new Vector2(Math.floorDiv(x, chunkSize), Math.floorDiv(y, chunkSize)));

        if (chunk != null) {
            int chunkCellX;
            int chunkCellY;

            // Positive and negative coordinates must be treated differently!
            if (x < 0) {
                chunkCellX = chunkSize - (Math.abs(x % chunkSize) > 0 ? Math.abs(x % chunkSize) : chunkSize);
            } else {
                chunkCellX = x % chunkSize;
            }
            if (y < 0) {
                chunkCellY = chunkSize -  (Math.abs(y % chunkSize) > 0 ? Math.abs(y % chunkSize) : chunkSize);
            } else {
                chunkCellY = y % chunkSize;
            }

            result = chunk.getCell(chunkCellX, chunkCellY);
        }

        return result;
    }

    public ArrayList<Entity> getEntities ( ) {
        ArrayList<Entity> entities = new ArrayList<>();
        for (Chunk chunk : this.chunks.values()) {
            entities.addAll(chunk.getEntities());
        }

        return entities;
    }

    public Cell getSpawn ( ) {
        return this.worldSpawn;
    }

    public HashMap<Vector2, Chunk> getChunks ( ) {
        return this.chunks;
    }

    public Chunk getChunk (Vector2 position) {
        return this.chunks.get(position);
    }

    public int getChunkSize ( ) {
        return this.chunkSize;
    }

    public enum CellEnum {
        EMPTY,
        GRASS,
        ICE,
        MARTIANSOIL;
    }
}